/*
 * 网卡性能和稳定性测试程序主入口
 * 功能：Linux下网卡各种性能、稳定性、链路状态测试
 * 支持：以太网卡性能测试、链路状态监控、网络延迟测试、带宽测试
 * 作者：test_code项目
 * 平台：Linux嵌入式系统
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include "phy_utils.h"

static volatile int running = 1;

void signal_handler(int sig) {
    if (sig == SIGINT || sig == SIGTERM) {
        printf("\n接收到退出信号，正在停止网卡测试...\n");
        running = 0;
    }
}

void print_usage(const char *program_name) {
    printf("用法: %s [选项]\n", program_name);
    printf("Linux网卡性能和稳定性测试程序\n\n");
    printf("选项:\n");
    printf("  -i, --interface=IFACE  网络接口名称 (默认: eth0)\n");
    printf("  -t, --test=TYPE        测试类型:\n");
    printf("                         link      - 链路状态测试\n");
    printf("                         speed     - 速度性能测试\n");
    printf("                         latency   - 延迟测试\n");
    printf("                         stability - 稳定性测试\n");
    printf("                         stress    - 压力测试\n");
    printf("                         monitor   - 实时监控\n");
    printf("                         all       - 所有测试\n");
    printf("  -h, --host=HOST        目标主机地址 (默认: 8.8.8.8)\n");
    printf("  -p, --port=PORT        目标端口 (默认: 80)\n");
    printf("  -s, --size=BYTES       数据包大小 (字节，默认: 1024)\n");
    printf("  -c, --count=NUM        测试次数 (默认: 100)\n");
    printf("  -d, --duration=SEC     测试持续时间 (秒，默认: 60)\n");
    printf("  -v, --verbose          详细输出模式\n");
    printf("  -f, --info             显示网络接口信息\n");
    printf("  --help                 显示帮助信息\n");
    printf("\n示例:\n");
    printf("  %s -f                              # 显示网络接口信息\n", program_name);
    printf("  %s -i eth0 -t link                # 链路状态测试\n", program_name);
    printf("  %s -i eth0 -t speed -h 192.168.1.1 # 速度测试\n", program_name);
    printf("  %s -i eth0 -t latency -c 1000     # 延迟测试\n", program_name);
    printf("  %s -i eth0 -t stability -d 300    # 5分钟稳定性测试\n", program_name);
    printf("  %s -i eth0 -t monitor             # 实时监控\n", program_name);
}

int run_link_test(const char *interface) {
    printf("=== 网卡链路状态测试 ===\n");
    printf("接口: %s\n", interface);
    
    // 获取接口基本信息
    phy_interface_info_t info;
    if (phy_get_interface_info(interface, &info) != 0) {
        printf("获取接口信息失败\n");
        return -1;
    }
    
    phy_print_interface_info(&info);
    
    // 测试链路状态
    printf("\n链路状态检测:\n");
    int link_up = phy_check_link_status(interface);
    printf("链路状态: %s\n", link_up ? "UP" : "DOWN");
    
    if (link_up) {
        // 获取链路速度和双工模式
        int speed = phy_get_link_speed(interface);
        int duplex = phy_get_duplex_mode(interface);
        printf("链路速度: %d Mbps\n", speed);
        printf("双工模式: %s\n", duplex ? "全双工" : "半双工");
        
        // 测试自协商状态
        int autoneg = phy_get_autoneg_status(interface);
        printf("自协商: %s\n", autoneg ? "启用" : "禁用");
    }
    
    // 连续监控链路状态
    printf("\n链路状态监控 (按Ctrl+C退出):\n");
    int prev_status = -1;
    while (running) {
        int current_status = phy_check_link_status(interface);
        if (current_status != prev_status) {
            time_t now = time(NULL);
            printf("[%s] 链路状态变化: %s\n", 
                   strtok(ctime(&now), "\n"), 
                   current_status ? "UP" : "DOWN");
            prev_status = current_status;
        }
        sleep(1);
    }
    
    return 0;
}

int run_speed_test(const char *interface, const char *target_host, int packet_size, int count) {
    printf("=== 网卡速度性能测试 ===\n");
    printf("接口: %s\n", interface);
    printf("目标主机: %s\n", target_host);
    printf("数据包大小: %d 字节\n", packet_size);
    printf("测试次数: %d\n", count);
    
    phy_speed_test_config_t config = {
        .packet_size = packet_size,
        .packet_count = count,
        .test_duration = 30,
        .tcp_test = 1,
        .udp_test = 1
    };
    
    phy_speed_test_result_t result;
    
    if (phy_run_speed_test(interface, target_host, &config, &result) != 0) {
        printf("速度测试失败\n");
        return -1;
    }
    
    phy_print_speed_test_result(&result);
    
    return 0;
}

int run_latency_test(const char *interface, const char *target_host, int count) {
    printf("=== 网卡延迟测试 ===\n");
    printf("接口: %s\n", interface);
    printf("目标主机: %s\n", target_host);
    printf("测试次数: %d\n", count);
    
    phy_latency_test_result_t result;
    
    if (phy_run_latency_test(interface, target_host, count, &result) != 0) {
        printf("延迟测试失败\n");
        return -1;
    }
    
    phy_print_latency_test_result(&result);
    
    return 0;
}

int run_stability_test(const char *interface, const char *target_host, int duration) {
    printf("=== 网卡稳定性测试 ===\n");
    printf("接口: %s\n", interface);
    printf("目标主机: %s\n", target_host);
    printf("测试时长: %d 秒\n", duration);
    
    phy_stability_test_config_t config = {
        .test_duration = duration,
        .ping_interval = 1,
        .packet_size = 64,
        .check_link_status = 1,
        .monitor_errors = 1
    };
    
    phy_stability_test_result_t result;
    
    printf("开始稳定性测试，按Ctrl+C提前结束...\n");
    
    if (phy_run_stability_test(interface, target_host, &config, &result) != 0) {
        printf("稳定性测试失败\n");
        return -1;
    }
    
    phy_print_stability_test_result(&result);
    
    return 0;
}

int run_stress_test(const char *interface, const char *target_host, int duration) {
    printf("=== 网卡压力测试 ===\n");
    printf("接口: %s\n", interface);
    printf("目标主机: %s\n", target_host);
    printf("测试时长: %d 秒\n", duration);
    
    phy_stress_test_config_t config = {
        .test_duration = duration,
        .concurrent_connections = 10,
        .packet_rate = 1000,
        .packet_size = 1400,
        .cpu_monitor = 1,
        .memory_monitor = 1
    };
    
    phy_stress_test_result_t result;
    
    printf("开始压力测试，按Ctrl+C提前结束...\n");
    
    if (phy_run_stress_test(interface, target_host, &config, &result) != 0) {
        printf("压力测试失败\n");
        return -1;
    }
    
    phy_print_stress_test_result(&result);
    
    return 0;
}

int run_monitor_mode(const char *interface) {
    printf("=== 网卡实时监控 ===\n");
    printf("接口: %s\n", interface);
    printf("按Ctrl+C退出监控模式...\n\n");
    
    phy_monitor_config_t config = {
        .update_interval = 1,
        .show_packets = 1,
        .show_bytes = 1,
        .show_errors = 1,
        .show_link_status = 1
    };
    
    if (phy_start_monitor(interface, &config) != 0) {
        printf("启动监控失败\n");
        return -1;
    }
    
    while (running) {
        phy_monitor_stats_t stats;
        if (phy_get_monitor_stats(interface, &stats) == 0) {
            phy_print_monitor_stats(&stats);
        }
        sleep(config.update_interval);
    }
    
    phy_stop_monitor(interface);
    
    return 0;
}

int run_comprehensive_test(const char *interface, const char *target_host) {
    printf("=== 网卡综合测试 ===\n");
    printf("接口: %s\n", interface);
    printf("目标主机: %s\n", target_host);
    
    int overall_result = 0;
    
    // 1. 链路状态测试
    printf("\n1. 链路状态测试\n");
    printf("================\n");
    if (run_link_test(interface) != 0) {
        printf("链路状态测试失败\n");
        overall_result = -1;
    }
    
    if (!running) return overall_result;
    
    // 2. 延迟测试
    printf("\n2. 延迟测试\n");
    printf("===========\n");
    if (run_latency_test(interface, target_host, 50) != 0) {
        printf("延迟测试失败\n");
        overall_result = -1;
    }
    
    if (!running) return overall_result;
    
    // 3. 速度测试
    printf("\n3. 速度测试\n");
    printf("===========\n");
    if (run_speed_test(interface, target_host, 1024, 100) != 0) {
        printf("速度测试失败\n");
        overall_result = -1;
    }
    
    if (!running) return overall_result;
    
    // 4. 短期稳定性测试
    printf("\n4. 稳定性测试\n");
    printf("==============\n");
    if (run_stability_test(interface, target_host, 60) != 0) {
        printf("稳定性测试失败\n");
        overall_result = -1;
    }
    
    printf("\n=== 综合测试完成 ===\n");
    printf("整体结果: %s\n", overall_result == 0 ? "通过" : "失败");
    
    return overall_result;
}

int main(int argc, char *argv[]) {
    char interface[32] = "eth0";
    char test_type[32] = "link";
    char target_host[256] = "8.8.8.8";
    int target_port = 80;
    int packet_size = 1024;
    int test_count = 100;
    int test_duration = 60;
    int verbose_mode = 0;
    int show_info = 0;
    
    // 长选项定义
    static struct option long_options[] = {
        {"interface", required_argument, 0, 'i'},
        {"test",      required_argument, 0, 't'},
        {"host",      required_argument, 0, 'h'},
        {"port",      required_argument, 0, 'p'},
        {"size",      required_argument, 0, 's'},
        {"count",     required_argument, 0, 'c'},
        {"duration",  required_argument, 0, 'd'},
        {"verbose",   no_argument,       0, 'v'},
        {"info",      no_argument,       0, 'f'},
        {"help",      no_argument,       0, '?'},
        {0, 0, 0, 0}
    };
    
    // 解析命令行参数
    int opt;
    int option_index = 0;
    while ((opt = getopt_long(argc, argv, "i:t:h:p:s:c:d:vf", long_options, &option_index)) != -1) {
        switch (opt) {
            case 'i':
                strncpy(interface, optarg, sizeof(interface) - 1);
                interface[sizeof(interface) - 1] = '\0';
                break;
            case 't':
                strncpy(test_type, optarg, sizeof(test_type) - 1);
                test_type[sizeof(test_type) - 1] = '\0';
                break;
            case 'h':
                strncpy(target_host, optarg, sizeof(target_host) - 1);
                target_host[sizeof(target_host) - 1] = '\0';
                break;
            case 'p':
                target_port = atoi(optarg);
                break;
            case 's':
                packet_size = atoi(optarg);
                break;
            case 'c':
                test_count = atoi(optarg);
                break;
            case 'd':
                test_duration = atoi(optarg);
                break;
            case 'v':
                verbose_mode = 1;
                break;
            case 'f':
                show_info = 1;
                break;
            case '?':
                print_usage(argv[0]);
                return 0;
            default:
                print_usage(argv[0]);
                return 1;
        }
    }
    
    // 注册信号处理器
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    
    printf("网卡测试程序启动\n");
    printf("========================\n");
    
    // 设置详细模式
    phy_set_verbose_mode(verbose_mode);
    
    // 显示网络接口信息
    if (show_info) {
        phy_show_all_interfaces();
        return 0;
    }
    
    // 参数有效性检查
    if (packet_size <= 0 || test_count <= 0 || test_duration <= 0) {
        printf("错误：数据包大小、测试次数和持续时间必须大于0\n");
        return 1;
    }
    
    // 检查网络接口是否存在
    if (!phy_interface_exists(interface)) {
        printf("错误：网络接口 '%s' 不存在\n", interface);
        printf("可用的网络接口:\n");
        phy_show_all_interfaces();
        return 1;
    }
    
    // 执行对应的测试
    int result = 0;
    if (strcmp(test_type, "link") == 0) {
        result = run_link_test(interface);
    } else if (strcmp(test_type, "speed") == 0) {
        result = run_speed_test(interface, target_host, packet_size, test_count);
    } else if (strcmp(test_type, "latency") == 0) {
        result = run_latency_test(interface, target_host, test_count);
    } else if (strcmp(test_type, "stability") == 0) {
        result = run_stability_test(interface, target_host, test_duration);
    } else if (strcmp(test_type, "stress") == 0) {
        result = run_stress_test(interface, target_host, test_duration);
    } else if (strcmp(test_type, "monitor") == 0) {
        result = run_monitor_mode(interface);
    } else if (strcmp(test_type, "all") == 0) {
        result = run_comprehensive_test(interface, target_host);
    } else {
        printf("错误：未知的测试类型 '%s'\n", test_type);
        printf("支持的测试类型: link, speed, latency, stability, stress, monitor, all\n");
        return 1;
    }
    
    if (result == 0) {
        printf("\n网卡测试完成\n");
    } else {
        printf("\n网卡测试失败\n");
    }
    
    return result;
}